<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="c73b3" id="c73b3"><span data-lake-id="u8f0f7c69" id="u8f0f7c69">典型回答</span></h1>
  <p data-lake-id="u9c302c1f" id="u9c302c1f"><br></p>
  <p data-lake-id="ud9efbddd" id="ud9efbddd"><span data-lake-id="u9b5279a4" id="u9b5279a4">MySQL中是可以存储emoji表情的，但是要使用UTF8MB4的字符编码才可以。如果是UTF8MB3的话，存储这些扩展字符的话会无法解析导致报错。</span></p>
  <p data-lake-id="u749d5d57" id="u749d5d57"><span data-lake-id="ufa21aeeb" id="ufa21aeeb">​</span><br></p>
  <h1 data-lake-id="fuV5d" id="fuV5d"><span data-lake-id="u68ac0654" id="u68ac0654">扩展知识</span></h1>
  <p data-lake-id="u59a4158c" id="u59a4158c"><br></p>
  <h2 data-lake-id="QoDu9" id="QoDu9"><span data-lake-id="ub9663de3" id="ub9663de3">MySQL对Unicode的支持</span></h2>
  <p data-lake-id="u02abbf8e" id="u02abbf8e"><br></p>
  <p data-lake-id="u0e78e15c" id="u0e78e15c"><span data-lake-id="ua32f5f66" id="ua32f5f66">Unicode字符集，他现在已经是计算机科学领域里的一项业界标准，它对世界上大部分的文字系统进行了整理、编码，使得计算机可以用更为简单的方式来呈现和处理文字。</span></p>
  <p data-lake-id="uc6770218" id="uc6770218"><br></p>
  <p data-lake-id="uc8e9d5ca" id="uc8e9d5ca"><span data-lake-id="u02c08611" id="u02c08611">为了适应不同的数据存储和传递需求，人们提出了 Unicode Transformation Format（UTF）系列编码。这其中包含UTF-8、UTF-16、UTF-32等。</span></p>
  <p data-lake-id="u3967169a" id="u3967169a"><br></p>
  <p data-lake-id="u397d6300" id="u397d6300"><span data-lake-id="u3761853a" id="u3761853a">通过查阅MySQL官方文档（</span><a href="https://dev.mysql.com/doc/refman/8.0/en/charset-unicode.html" target="_blank" data-lake-id="u206d4c65" id="u206d4c65"><span data-lake-id="u7b6f533a" id="u7b6f533a">https://dev.mysql.com/doc/refman/8.0/en/charset-unicode.html</span></a><span data-lake-id="u35096329" id="u35096329"> ），我们可以知道，</span><strong><span data-lake-id="u49242cf0" id="u49242cf0">在MySQL中，主要支持以下字符集：utf8、ucs2、utf8mb3、utf8mb4、utf16、utf16le和utf32</span></strong></p>
  <p data-lake-id="u111e65d1" id="u111e65d1"><br></p>
  <p data-lake-id="u91566660" id="u91566660"><span data-lake-id="uf7a2f5a1" id="uf7a2f5a1">不同的字符集的区别在于包含的字符情况以及存储需要的空间。</span></p>
  <table data-lake-id="44e3c018" id="44e3c018" margin="true" class="lake-table" style="width: 750px">
   <colgroup>
    <col width="250">
    <col width="250">
    <col width="250">
   </colgroup>
   <tbody>
    <tr data-lake-id="u15b9380b" id="u15b9380b">
     <td data-lake-id="udf5abdf1" id="udf5abdf1">
      <p data-lake-id="u8a13a59f" id="u8a13a59f"><span data-lake-id="ubf6ab96c" id="ubf6ab96c">字符集</span></p></td>
     <td data-lake-id="ue2474af2" id="ue2474af2">
      <p data-lake-id="u738d4b47" id="u738d4b47"><span data-lake-id="u1371490c" id="u1371490c">支持的字符</span></p></td>
     <td data-lake-id="u46288f9d" id="u46288f9d">
      <p data-lake-id="ueda19443" id="ueda19443"><span data-lake-id="ud9999c76" id="ud9999c76">每个字符所需存储空间</span></p></td>
    </tr>
    <tr data-lake-id="u77e49192" id="u77e49192">
     <td data-lake-id="ue17abc66" id="ue17abc66">
      <p data-lake-id="u7f746576" id="u7f746576"><span data-lake-id="ucc93e4ef" id="ucc93e4ef">utf8mb3, utf8</span></p></td>
     <td data-lake-id="uea7d4c6c" id="uea7d4c6c">
      <p data-lake-id="u9bfdae30" id="u9bfdae30"><span data-lake-id="uf9308760" id="uf9308760">BMP</span></p></td>
     <td data-lake-id="u6ca9815e" id="u6ca9815e">
      <p data-lake-id="uafde47cf" id="uafde47cf"><span data-lake-id="u959a9e37" id="u959a9e37">1-3 字节</span></p></td>
    </tr>
    <tr data-lake-id="u02eaac0b" id="u02eaac0b">
     <td data-lake-id="u950e8902" id="u950e8902">
      <p data-lake-id="ua09ab91b" id="ua09ab91b"><span data-lake-id="u8e233893" id="u8e233893">ucs2</span></p></td>
     <td data-lake-id="ub7aa826b" id="ub7aa826b">
      <p data-lake-id="u9311ca0d" id="u9311ca0d"><span data-lake-id="uab198d83" id="uab198d83">BMP</span></p></td>
     <td data-lake-id="u3c53c199" id="u3c53c199">
      <p data-lake-id="udc40538c" id="udc40538c"><span data-lake-id="u1bd4b342" id="u1bd4b342">2 字节</span></p></td>
    </tr>
    <tr data-lake-id="u860864ec" id="u860864ec">
     <td data-lake-id="ud3123517" id="ud3123517">
      <p data-lake-id="u72581734" id="u72581734"><span data-lake-id="u87e91376" id="u87e91376">utf8mb4</span></p></td>
     <td data-lake-id="u8a459aa5" id="u8a459aa5">
      <p data-lake-id="uace30f47" id="uace30f47"><span data-lake-id="u3d8cf7dc" id="u3d8cf7dc">BMP和补充字符</span></p></td>
     <td data-lake-id="u403d3f4d" id="u403d3f4d">
      <p data-lake-id="ufbd1372d" id="ufbd1372d"><span data-lake-id="ubf2617ea" id="ubf2617ea">1-4 字节</span></p></td>
    </tr>
    <tr data-lake-id="ua65a68ad" id="ua65a68ad">
     <td data-lake-id="u47de2efe" id="u47de2efe">
      <p data-lake-id="u62509de4" id="u62509de4"><span data-lake-id="uac178a60" id="uac178a60">utf16</span></p></td>
     <td data-lake-id="u61dfd71b" id="u61dfd71b">
      <p data-lake-id="u6cde6637" id="u6cde6637"><span data-lake-id="ue6a51bde" id="ue6a51bde">BMP和补充字符</span></p></td>
     <td data-lake-id="u08f7f99a" id="u08f7f99a">
      <p data-lake-id="uda477c46" id="uda477c46"><span data-lake-id="u862728c8" id="u862728c8">2或4 字节</span></p></td>
    </tr>
    <tr data-lake-id="u98010bbb" id="u98010bbb">
     <td data-lake-id="u69ed0a18" id="u69ed0a18">
      <p data-lake-id="u863d0e57" id="u863d0e57"><span data-lake-id="u078948e8" id="u078948e8">utf16le</span></p></td>
     <td data-lake-id="uaaaa8e9e" id="uaaaa8e9e">
      <p data-lake-id="u81b86fec" id="u81b86fec"><span data-lake-id="u177e3652" id="u177e3652">BMP和补充字符</span></p></td>
     <td data-lake-id="ua0381ca9" id="ua0381ca9">
      <p data-lake-id="uc3e869e3" id="uc3e869e3"><span data-lake-id="u20616ac3" id="u20616ac3">2或4 字节</span></p></td>
    </tr>
    <tr data-lake-id="u04897c5d" id="u04897c5d">
     <td data-lake-id="u72cc46ac" id="u72cc46ac">
      <p data-lake-id="u17946a7f" id="u17946a7f"><span data-lake-id="u22e209f0" id="u22e209f0">utf32</span></p></td>
     <td data-lake-id="u69fd791e" id="u69fd791e">
      <p data-lake-id="u4dfcbac1" id="u4dfcbac1"><span data-lake-id="uc71ae506" id="uc71ae506">BMP和补充字符</span></p></td>
     <td data-lake-id="uaf86ee78" id="uaf86ee78">
      <p data-lake-id="u18e09b12" id="u18e09b12"><span data-lake-id="u6669c536" id="u6669c536">4 字节</span></p></td>
    </tr>
   </tbody>
  </table>
  <p data-lake-id="ud3652fd0" id="ud3652fd0"><br></p>
  <p data-lake-id="u6187b226" id="u6187b226"><span data-lake-id="u7ff903c4" id="u7ff903c4">在MySQL官方文档中，介绍了支持的编码方式之后，还有一段醒目的提醒：</span></p>
  <p data-lake-id="ub31757d5" id="ub31757d5"><br></p>
  <p data-lake-id="u1ac6906f" id="u1ac6906f"><img src="http://www.hollischuang.com/wp-content/uploads/2021/05/16205427559305.jpg?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_60%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"><span data-lake-id="u8cc64b07" id="u8cc64b07">​</span></p>
  <p data-lake-id="u72128a80" id="u72128a80"><br></p>
  <p data-lake-id="u9a33d1d5" id="u9a33d1d5"><span data-lake-id="u741fe6d2" id="u741fe6d2">翻译过来是：</span><strong><span data-lake-id="ud3d15d1c" id="ud3d15d1c">utf8mb3字符集已被弃用，它在未来的MySQL版本中将会被删除，请使用utf8mb4代替。在目前的8.0版本中，utf8指的就是utf8mb3，虽然未来可能改成utf8mb4，但是为了避免产生歧义，可以考虑为字符集引用显式指定utf8mb4，而不是utf8。</span></strong></p>
  <p data-lake-id="u125a3405" id="u125a3405"><br></p>
  <p data-lake-id="u2d7e0396" id="u2d7e0396"><span data-lake-id="u828d00f8" id="u828d00f8">也就是说，当我们在MySQL 8.0 中指定字符编码方式为UTF-8的时候，其实使用的是utf8mb3这种编码方式。</span></p>
  <p data-lake-id="ua7e37f84" id="ua7e37f84"><br></p>
  <p data-lake-id="u014ad556" id="u014ad556"><span data-lake-id="u5b182f12" id="u5b182f12">那么，我们先来说说utf8mb3。</span></p>
  <p data-lake-id="u567e988e" id="u567e988e"><br></p>
  <h2 data-lake-id="EzCT9" id="EzCT9"><span data-lake-id="u00408458" id="u00408458">utf8mb3</span></h2>
  <p data-lake-id="ubfe8397b" id="ubfe8397b"><br></p>
  <p data-lake-id="u65fba98c" id="u65fba98c"><span data-lake-id="u87e336e4" id="u87e336e4">utf8mb3字符集是MySQL早期就支持的字符集，他具有以下特征:</span></p>
  <p data-lake-id="u8bed5bdd" id="u8bed5bdd"><br></p>
  <p data-lake-id="u187fb2ef" id="u187fb2ef"><span data-lake-id="ubf7d1c23" id="ubf7d1c23">1、仅支持BMP字符(不支持补充字符)</span></p>
  <p data-lake-id="u588cd1a6" id="u588cd1a6"><br></p>
  <p data-lake-id="u1a852ccb" id="u1a852ccb"><span data-lake-id="u4866ab8b" id="u4866ab8b">2、每个多字节字符最多需要三个字节</span></p>
  <p data-lake-id="u5d3a97f7" id="u5d3a97f7"><br></p>
  <p data-lake-id="ubedd4562" id="ubedd4562"><span data-lake-id="u3945ddc8" id="u3945ddc8">注意，仅支持BMP字符，那么什么是BMP字符呢？</span></p>
  <p data-lake-id="u0f6e0ec3" id="u0f6e0ec3"><br></p>
  <p data-lake-id="u1d448a86" id="u1d448a86"><span data-lake-id="udcde969b" id="udcde969b">BMP是Basic Multilingual Plane的缩写，即码位在0到65535之间(或者U+0000和U+FFFF)的字符。</span></p>
  <p data-lake-id="u5509978d" id="u5509978d"><br></p>
  <p data-lake-id="ua66547c5" id="ua66547c5"><strong><span data-lake-id="u7dde93d7" id="u7dde93d7">BMP中并不包含补充字符</span></strong><span data-lake-id="ufe91cc52" id="ufe91cc52">，即码位在U+10000和U+10FFFF之间的的字符。补充字符有哪些呢，如一些生僻的汉字，或者Emoji 表情等都是补充字符。</span></p>
  <p data-lake-id="u8dd2f4fe" id="u8dd2f4fe"><br></p>
  <p data-lake-id="u598d6fbe" id="u598d6fbe"><strong><span data-lake-id="ud99975e8" id="ud99975e8">也就是说，如果在建表的时候，指定的编码方式是utf8mb3（utf-8），那么对于一些生僻字或者emoji表情都无法表示。</span></strong></p>
  <p data-lake-id="ueeee745c" id="ueeee745c"><br></p>
  <h2 data-lake-id="gBCF9" id="gBCF9"><span data-lake-id="u7e43f52f" id="u7e43f52f">utf8mb4</span></h2>
  <p data-lake-id="u30c6ba15" id="u30c6ba15"><br></p>
  <p data-lake-id="ua95a6cfe" id="ua95a6cfe"><span data-lake-id="uad5651b2" id="uad5651b2">早期的时候，Unicode 只用到了 0~0xFFFF 范围的数字编码，这就是 BMP 字符集。所以，最初MySQL在设计之初，也就只涉及了包含BMP 字符集的utfmb3(utf-8)，但是随着文字越来越多，3个字节肯定无法全部表示，于是Unicode支持的字符就更多了。</span></p>
  <p data-lake-id="ue1889035" id="ue1889035"><br></p>
  <p data-lake-id="u746e4ffe" id="u746e4ffe"><span data-lake-id="u2ea2de12" id="u2ea2de12">所以，早期的utfmb3在有些场景中就不能满足需求了，于是，</span><strong><span data-lake-id="ue4abe6df" id="ue4abe6df">MySQL在5.5.3之后增加了utf8mb4的编码。</span></strong></p>
  <p data-lake-id="uacc37c89" id="uacc37c89"><br></p>
  <p data-lake-id="ub367e462" id="ub367e462"><span data-lake-id="u8709f695" id="u8709f695">utfmb4字符集具有以下特征:</span></p>
  <p data-lake-id="u9ea36ae7" id="u9ea36ae7"><br></p>
  <p data-lake-id="u9ad6ee11" id="u9ad6ee11"><span data-lake-id="u7db1f61c" id="u7db1f61c">1、支持BMP和补充字符。</span></p>
  <p data-lake-id="uae60e669" id="uae60e669"><br></p>
  <p data-lake-id="u1b34b58c" id="u1b34b58c"><span data-lake-id="u3d83e2ec" id="u3d83e2ec">2、每个多字节字符最多需要4个字节。</span></p>
  <p data-lake-id="uc730f83f" id="uc730f83f"><br></p>
  <p data-lake-id="udefa6d25" id="udefa6d25"><span data-lake-id="u3a3ec2cc" id="u3a3ec2cc">utf8mb4与utf8mb3字符集不同，utf8mb3字符集只支持BMP字符，每个字符最多使用三个字节:</span></p>
  <p data-lake-id="u6cab2d47" id="u6cab2d47"><br></p>
  <p data-lake-id="ud527bb4d" id="ud527bb4d"><span data-lake-id="u926341a2" id="u926341a2">对于BMP字符，utf8mb4和utf8mb3具有相同的存储特征，即相同的编码值，相同的编码，相同的长度。</span></p>
  <p data-lake-id="u7e5152e2" id="u7e5152e2"><br></p>
  <p data-lake-id="ue2798ebc" id="ue2798ebc"><span data-lake-id="u0498e3e1" id="u0498e3e1">对于补充字符，utf8mb4需要4个字节来存储它，而utf8mb3根本不能存储该字符。所以我们说utf8mb4是utf8mb3的超集。</span></p>
  <p data-lake-id="u918ecbcb" id="u918ecbcb"><br></p>
  <p data-lake-id="u7c53f1fa" id="u7c53f1fa"><strong><span data-lake-id="uebf663be" id="uebf663be">所以，很多时候，为了考虑到兼容性，建议创建MySQL表的时候，使用utf8mb4，而不是utf8！</span></strong></p>
  <p data-lake-id="u96532f65" id="u96532f65"><br></p>
  <h2 data-lake-id="Wm0W5" id="Wm0W5"><span data-lake-id="u590d9eae" id="u590d9eae">utf8mb3和utf8mb4区别及优缺点</span></h2>
  <p data-lake-id="u05921bde" id="u05921bde"><br></p>
  <p data-lake-id="ubecc67cd" id="ubecc67cd"><span data-lake-id="u67c6b886" id="u67c6b886">前面分别介绍了utf8mb3和utf8mb4字符集，他们的区别如下:</span></p>
  <p data-lake-id="u32616091" id="u32616091"><br></p>
  <p data-lake-id="u24bf1554" id="u24bf1554"><strong><span data-lake-id="ub3dab8d3" id="ub3dab8d3">utf8mb3只支持BMP (Basic Multilingual Plane)的字符。utf8mb4还支持BMP之外的补充字符。</span></strong></p>
  <p data-lake-id="u23b3c9a9" id="u23b3c9a9"><br></p>
  <p data-lake-id="u1e8c6004" id="u1e8c6004"><strong><span data-lake-id="ua4ce2b4a" id="ua4ce2b4a">utf8mb3每个字符最多使用3个字节。Utf8mb4每个字符最多使用4个字节。</span></strong></p>
  <p data-lake-id="u971a4b2c" id="u971a4b2c"><br></p>
  <p data-lake-id="u62a11b4c" id="u62a11b4c"><span data-lake-id="u0490e2d4" id="u0490e2d4">utf8mb4比utf8mb3来说，他能表示更多的补充字符，但是同时占用的空间可能会更大一些。</span></p>
  <p data-lake-id="u23acf110" id="u23acf110"><br></p>
  <h2 data-lake-id="URZF4" id="URZF4"><span data-lake-id="ue6a4dbfc" id="ue6a4dbfc">从utf8mb3转换成utf8mb4</span></h2>
  <p data-lake-id="ua225c859" id="ua225c859"><br></p>
  <p data-lake-id="ua46c58bb" id="ua46c58bb"><span data-lake-id="ub74ad205" id="ub74ad205">首先，想要把字符集从utf8mb3转换到utf8mb4，其实是问题不大的:</span></p>
  <p data-lake-id="u5cc8d4d5" id="u5cc8d4d5"><br></p>
  <p data-lake-id="udfba2204" id="udfba2204"><span data-lake-id="u065e4256" id="u065e4256">对于BMP字符，utf8mb4和utf8mb3具有相同的存储特征:相同的编码值，相同的编码，相同的长度。</span></p>
  <p data-lake-id="u6a668772" id="u6a668772"><br></p>
  <p data-lake-id="u1751f191" id="u1751f191"><span data-lake-id="u91776c94" id="u91776c94">对于补充字符，utf8mb4需要4个字节来存储它，而utf8mb3根本不能存储该字符。当将utf8mb3列转换为utf8mb4时，您不必担心转换补充字符，因为没有补充字符。</span></p>
  <p data-lake-id="u8e0d7ea7" id="u8e0d7ea7"><br></p>
  <p data-lake-id="u3ff9f540" id="u3ff9f540"><span data-lake-id="u253eb876" id="u253eb876">假设有一张已知表使用了utf8mb3：</span></p>
  <p data-lake-id="u6a6c5d13" id="u6a6c5d13"><br></p>
  <pre lang="java"><code>
CREATE TABLE t1 (
  col1 CHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  col2 CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
) CHARACTER SET utf8;
</code></pre>
  <p data-lake-id="u6b5c06bc" id="u6b5c06bc"><br></p>
  <p data-lake-id="u85a3f557" id="u85a3f557"><span data-lake-id="u73d71b7d" id="u73d71b7d">下面的语句将t1转换为utf8mb4:</span></p>
  <p data-lake-id="u403ab1ab" id="u403ab1ab"><br></p>
  <pre lang="java"><code>
ALTER TABLE t1
  DEFAULT CHARACTER SET utf8mb4,
  MODIFY col1 CHAR(10)
    CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  MODIFY col2 CHAR(10)
    CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL;
</code></pre>
  <p data-lake-id="uc0a38e8f" id="uc0a38e8f"><br></p>
  <p data-lake-id="uf7cd5041" id="uf7cd5041"><span data-lake-id="ue6147ab0" id="ue6147ab0">​</span><br></p>
 </body>
</html>